package com.google.code.p.restrpc.client.cluster;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.code.p.restrpc.RpcException;
import com.google.code.p.restrpc.RpcRequest;
import com.google.code.p.restrpc.RpcResponse;
import com.google.code.p.restrpc.client.event.AsyncRpcEventUtils;
import com.google.code.p.restrpc.client.loadbalance.LoadBalanceFailedException;
import com.google.code.p.restrpc.client.proxy.RemoteNodeRefusedException;

/**
 * @author dz
 */
public class FailFastStrategy extends AbstractFailureRecoveryStrategy {
    
    private static final Log logger = LogFactory.getLog(FailFastStrategy.class);
    
    @Override
    public RpcResponse invoke(ClusteredRpcContext context,
                              List<RpcRequest> requests) throws RpcException {
        int selectedPath = context.getLoadBalanceStrategy()
                                  .select(context.getRpcContext()
                                                 .getServiceName(),
                                          context.getRpcContext()
                                                 .getMethodName(),
                                          requests.toArray(new RpcRequest[] {}));
        if (selectedPath < 0) {
            throw new LoadBalanceFailedException("Can't determine the destination of rpcRequest!");
        }
        final RpcRequest rpcRequest = requests.get(selectedPath);
        try {
            RpcResponse result = context.getRestInvoker().send(rpcRequest);
            if (result.isSucceed() && rpcRequest.isAsync()) {
                AsyncRpcEventUtils.publishAsyncRpcEvent(context.getRpcContext(),
                                                        rpcRequest);
            }
            return result;
        }
        catch (RemoteNodeRefusedException e) {
            logger.error(e, e);
            disableRemoteServiceDefinition(context, rpcRequest);
            throw e;
        }
    }
}
